print('calculating the number of cells in the problem space')
from define_geometry import *
from define_problem_space_parameters import *

number_of_bricks = 0
number_of_spheres = 0
number_of_thin_wires = 0
number_of_bricks = len(bricks)
number_of_spheres = len(spheres)
number_of_thin_wires = len(thin_wires)

# find the minimum and maximum coordinates of a 
# box encapsulating the objects
fdtd_domain={"min_x":1e100,"min_y":1e100,"min_z":1e100,"max_x":-1e100,"max_y":-1e100,"max_z":-1e100}

for ind in np.arange(number_of_spheres):
    fdtd_domain["min_x"] = np.min([fdtd_domain["min_x"],spheres[ind]["center_x"] - spheres[ind]["radius"]])
    fdtd_domain["min_y"] = np.min([fdtd_domain["min_y"],spheres[ind]["center_y"] - spheres[ind]["radius"]])
    fdtd_domain["min_z"] = np.min([fdtd_domain["min_z"],spheres[ind]["center_z"] - spheres[ind]["radius"]])
    fdtd_domain["max_x"] = np.max([fdtd_domain["max_x"],spheres[ind]["center_x"] + spheres[ind]["radius"]])
    fdtd_domain["max_y"] = np.max([fdtd_domain["max_y"],spheres[ind]["center_y"] + spheres[ind]["radius"]])
    fdtd_domain["max_z"] = np.max([fdtd_domain["max_z"],spheres[ind]["center_z"] + spheres[ind]["radius"]])

for ind in np.arange(number_of_bricks):
    fdtd_domain["min_x"] = np.min([fdtd_domain["min_x"],bricks[ind]["min_x"]])
    fdtd_domain["min_y"] = np.min([fdtd_domain["min_y"],bricks[ind]["min_y"]]) 
    fdtd_domain["min_z"] = np.min([fdtd_domain["min_z"],bricks[ind]["min_z"]]) 
    fdtd_domain["max_x"] = np.max([fdtd_domain["max_x"],bricks[ind]["max_x"]]) 
    fdtd_domain["max_y"] = np.max([fdtd_domain["max_y"],bricks[ind]["max_y"]]) 
    fdtd_domain["max_z"] = np.max([fdtd_domain["max_z"],bricks[ind]["max_z"]]) 

for ind in np.arange(number_of_thin_wires):
    fdtd_domain["min_x"] = np.min([fdtd_domain["min_x"],thin_wires[ind]["min_x"]]) 
    fdtd_domain["min_y"] = np.min([fdtd_domain["min_y"],thin_wires[ind]["min_y"]]) 
    fdtd_domain["min_z"] = np.min([fdtd_domain["min_z"],thin_wires[ind]["min_z"]]) 
    fdtd_domain["max_x"] = np.max([fdtd_domain["max_x"],thin_wires[ind]["max_x"]]) 
    fdtd_domain["max_y"] = np.max([fdtd_domain["max_y"],thin_wires[ind]["max_y"]]) 
    fdtd_domain["max_z"] = np.max([fdtd_domain["max_z"],thin_wires[ind]["max_z"]]) 

# Determine the problem space boundaries including air buffers 
fdtd_domain["min_x"] = fdtd_domain["min_x"] - dx * boundary["air_buffer_number_of_cells_xn"]
fdtd_domain["min_y"] = fdtd_domain["min_y"] - dy * boundary["air_buffer_number_of_cells_yn"]
fdtd_domain["min_z"] = fdtd_domain["min_z"] - dz * boundary["air_buffer_number_of_cells_zn"]
fdtd_domain["max_x"] = fdtd_domain["max_x"] + dx * boundary["air_buffer_number_of_cells_xp"]
fdtd_domain["max_y"] = fdtd_domain["max_y"] + dy * boundary["air_buffer_number_of_cells_yp"]
fdtd_domain["max_z"] = fdtd_domain["max_z"] + dz * boundary["air_buffer_number_of_cells_zp"]

# Determine the problem space boundaries including cpml layers
if (boundary["type_xn"]== 'cpml') and (boundary["cpml_number_of_cells_xn"]>0):
    fdtd_domain["min_x"] = fdtd_domain["min_x"]- dx * boundary["cpml_number_of_cells_xn"]
if (boundary["type_xp"]== 'cpml') and (boundary["cpml_number_of_cells_xp"]>0):
    fdtd_domain["max_x"] = fdtd_domain["max_x"]+ dx * boundary["cpml_number_of_cells_xp"]
if (boundary["type_yn"]== 'cpml') and (boundary["cpml_number_of_cells_yn"]>0):
    fdtd_domain["min_y"] = fdtd_domain["min_y"]- dy * boundary["cpml_number_of_cells_yn"]
if (boundary["type_yp"]== 'cpml') and (boundary["cpml_number_of_cells_yp"]>0):
    fdtd_domain["max_y"] = fdtd_domain["max_y"]+ dy * boundary["cpml_number_of_cells_yp"]
if (boundary["type_zn"]== 'cpml') and (boundary["cpml_number_of_cells_zn"]>0):
    fdtd_domain["min_z"] = fdtd_domain["min_z"]- dz * boundary["cpml_number_of_cells_zn"]
if (boundary["type_zp"]== 'cpml') and (boundary["cpml_number_of_cells_zp"]>0):
    fdtd_domain["max_z"] = fdtd_domain["max_z"]+ dz * boundary["cpml_number_of_cells_zp"]

# Determining the problem space size
fdtd_domain["size_x"] = fdtd_domain["max_x"] - fdtd_domain["min_x"]
fdtd_domain["size_y"] = fdtd_domain["max_y"] - fdtd_domain["min_y"]
fdtd_domain["size_z"] = fdtd_domain["max_z"] - fdtd_domain["min_z"]

from define_problem_space_parameters import icoat_pool
from environment_pool import mesh_type_pool
if(mesh_type_pool==0):
    # number of cells in x, y, and z directions
    nx = round(fdtd_domain["size_x"]/dx)  
    ny = round(fdtd_domain["size_y"]/dy)
    nz = round(fdtd_domain["size_z"]/dz)
else:
    nx,ny,nz = icoat_pool.shape
    nx = nx + boundary["cpml_number_of_cells_xn"]+ boundary["cpml_number_of_cells_xp"]
    ny = ny + boundary["cpml_number_of_cells_yn"]+ boundary["cpml_number_of_cells_yp"]
    nz = nz + boundary["cpml_number_of_cells_zn"]+ boundary["cpml_number_of_cells_zp"]
    
    fdtd_domain["min_x"] = mesh_x0_pool
    fdtd_domain["min_y"] = mesh_y0_pool
    fdtd_domain["min_z"] = mesh_z0_pool
# adjust domain size by snapping to cells
fdtd_domain["size_x"] = nx * dx
fdtd_domain["size_y"] = ny * dy
fdtd_domain["size_x"] = nz * dz

fdtd_domain["max_x"] = fdtd_domain["min_x"] + fdtd_domain["size_x"]
fdtd_domain["max_y"] = fdtd_domain["min_y"] + fdtd_domain["size_y"]
fdtd_domain["max_z"] = fdtd_domain["min_z"] + fdtd_domain["size_z"]

# some frequently used auxiliary parameters 
nxp1 = nx+1    
nyp1 = ny+1    
nzp1 = nz+1
nxm1 = nx-1    
nxm2 = nx-2	
nym1 = ny-1
nym2 = ny-2	
nzm1 = nz-1	
nzm2 = nz-2

fdtd_domain["dx"] = dx
fdtd_domain["dy"] = dy
fdtd_domain["dz"] = dz

# create arrays storing the center coordinates of the cells
fdtd_domain["cell_center_x"] = np.zeros((nx,ny,nz))
fdtd_domain["cell_center_y"] = np.zeros((nx,ny,nz))
fdtd_domain["cell_center_z"] = np.zeros((nx,ny,nz))

for ind in np.arange(nx):
    fdtd_domain["cell_center_x"][ind,:,:] = (ind + 0.5) * dx + fdtd_domain["min_x"]

for ind in np.arange(ny):
    fdtd_domain["cell_center_y"][:,ind,:] = (ind + 0.5) * dy + fdtd_domain["min_y"]

for ind in np.arange(nz):
    fdtd_domain["cell_center_z"][:,:,ind] = (ind + 0.5) * dz + fdtd_domain["min_z"]
